package com.hb.trade.server.center.sys.controller;

import cn.hutool.core.collection.CollUtil;
import com.hb.core.pojo.center.au.entity.User;
import com.hb.core.pojo.center.sys.dto.CascadeQueryDTO;
import com.hb.core.pojo.center.sys.dto.MenuResourceDTO;
import com.hb.core.pojo.center.sys.entity.MenuResource;
import com.hb.core.pojo.parent.MPBaseController;
import com.hb.core.pojo.parent.MPCommonEntity;
import com.hb.trade.server.center.au.manager.UserManager;
import com.hb.trade.server.center.au.service.UserService;
import com.hb.trade.server.center.sys.service.DicCodeService;
import com.hb.trade.server.center.sys.service.MenuResourceService;
import org.fzzn.core.model.msg.Message;
import org.fzzn.core.model.enums.MsgEnum;
import org.fzzn.core.util.MsgUtil;
import org.fzzn.core.util.encrypt.PinyinUtil;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.Comparator;
import java.util.List;

/**
 * 目录资源信息表 前端控制器
 *
 * @author zjk
 * @since 2021-05-21
 */
@RestController
public class MenuResourceController extends MPBaseController<MenuResource, MenuResourceService> {

    protected final UserService userService;
    protected final DicCodeService dicCodeService;

    public MenuResourceController(MenuResourceService service,
                                  UserService userService,
                                  DicCodeService dicCodeService) {
        super(service);
        this.userService = userService;
        this.dicCodeService = dicCodeService;
    }

    /**
     * 新增一个菜单
     *
     * @param menuDto
     * @return
     */
    @PostMapping("/menuResource/addMenu")
    public Message<Boolean> addMenu(@RequestBody MenuResourceDTO menuDto) {
        boolean save = service.save(menuDto);
        return MsgUtil.success(save);
    }

    /**
     * 新增一个菜单
     *
     * @param menuId
     * @return
     */
    @PostMapping("/menuResource/removeMenu")
    public Message<Boolean> removeMenu(Long menuId) {
        if (menuId == null) {
            return MsgUtil.msg(MsgEnum.INCORRECT_PARAM);
        }

        // 级联删除子集数据
        CascadeQueryDTO queryDTO = new CascadeQueryDTO();
        queryDTO.setId(menuId);
        queryDTO.setTableName("sys_menu_resource");
        List<Long> ids = dicCodeService.getChildList(queryDTO);

        for (Long id : ids) {
            markDeleteById(id);
        }

        return MsgUtil.success(true);
    }

    /**
     * 修改菜单信息
     *
     * @param menuResource
     * @return
     */
    @PostMapping("/menuResource/updateMenuResource")
    public Message<Boolean> updateMenuResource(@RequestBody MenuResourceDTO menuResource) {
        Long id = menuResource.getId();
        if (id == null) {
            return MsgUtil.msg(MsgEnum.INCORRECT_PARAM);
        }
        MenuResource resource = service.getById(id);
        menuResource.to(resource);
        // 设置权限代码
        resource.setAuthCode(PinyinUtil.getPingYin(resource.getResName()));
        boolean update = service.updateById(resource);
        return MsgUtil.success(update);
    }

    /**
     * 查询一个菜单详情
     *
     * @param menuId
     * @return
     */
    @PostMapping("/menuResource/getMenu")
    public Message<MenuResource> getMenu(Long menuId) {
        MenuResource resource = getById(menuId);
        if (resource == null) {
            return MsgUtil.msg(MsgEnum.NULL_RESULT);
        }
        return MsgUtil.success(resource);
    }

    /**
     * 指定用户的左侧导航栏菜单
     *
     * @param menuResource
     * @return
     */
    @PostMapping("/menuResource/listTrees")
    public Message<List<MenuResourceDTO>> listTrees(@RequestBody MenuResourceDTO menuResource) {
        Long currentUserId = menuResource.getUserId();
        User user;
        if (currentUserId == null) {
            user = null;
        } else {
            user = userService.getById(currentUserId);
        }

        List<MenuResourceDTO> menus;
        if (menuResource.getRoleId() != null) {
            // 查询指定角色的菜单
            menus = service.listMenusByRoleId(menuResource.getRoleId());
        } else if (user == null || user.to(UserManager.class).isAdmin()) {
            // * 用户为空时表示菜单维护列表时调用接口 * //
            // 查询所有菜单
            menus = service.listAllMenus(menuResource);
        } else {
            // 查询该用户能看到的菜单
            menus = service.listTreesWithAuth(currentUserId, menuResource.getRoleSign());
        }
        return MsgUtil.success(menus);
    }

    /**
     * 获取当前登录用户和指定角色所能分配的权限合集
     *
     * @param userId 用户ID
     * @param roleId 角色ID
     * @return
     */
    @PostMapping("/menuResource/currentWithRoleId")
    public Message<List<MenuResourceDTO>> currentWithRoleId(Long userId, Long roleId) {
        // 如果是超级管理员直接返回全部菜单
        User user = userService.getById(userId);
        UserManager userEntity = user.to(UserManager.class);
        if (userEntity.isAdmin()) {
            MenuResourceDTO resourceDTO = new MenuResourceDTO();
            resourceDTO.setActiveMenu(1);
            List<MenuResourceDTO> menus = service.listAllMenus(resourceDTO);
            if (CollUtil.isEmpty(menus)) {
                return MsgUtil.msg(MsgEnum.NULL_RESULT);
            }
            return MsgUtil.success(menus);
        }

        // ...其他用户
        List<MenuResourceDTO> menus = CollUtil.list(false);
        if (roleId != null) {
            // 查询指定角色的菜单
            menus.addAll(service.listMenusByRoleId(roleId));
        }
        // 查询该用户能看到的菜单
        menus.addAll(service.listTreesWithAuth(userId, null));

        CollUtil.filter(menus, (item) -> Integer.valueOf(1).equals(item.getActiveMenu()));
        CollUtil.sort(menus, Comparator.comparing(MenuResource::getParentId));
        return MsgUtil.success(menus);
    }


    /**
     * 获取指定角色已拥有的权限集合
     *
     * @param roleId 角色ID
     * @return
     */
    @PostMapping("/menuResource/authByRoleId")
    public Message<List<MenuResourceDTO>> authByRoleId(Long roleId) {
        List<MenuResourceDTO> menus = CollUtil.list(false);

        if (roleId != null) {
            // 查询指定角色的菜单
            menus.addAll(service.listMenusByRoleId(roleId));
        }

        return MsgUtil.success(menus);
    }
}
